package com.ycsd.invest.order.business.formplugin;

import com.alibaba.druid.util.StringUtils;
import com.ycsd.invest.order.common.utils.DynamicObjectUtil;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.clr.CollectionProperty;
import kd.bos.dataentity.metadata.clr.ComplexProperty;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.events.BizDataEventArgs;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.plugin.Plugin;
import kd.bos.form.*;
import kd.bos.form.container.Tab;
import kd.bos.form.control.Control;
import kd.bos.form.control.events.BeforeClickEvent;
import kd.bos.form.control.events.BeforeItemClickEvent;
import kd.bos.form.control.events.TabSelectEvent;
import kd.bos.form.control.events.TabSelectListener;
import kd.bos.form.events.BeforeClosedEvent;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.form.events.MessageBoxClosedEvent;
import kd.bos.form.events.PreOpenFormEventArgs;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

import java.util.EventObject;
import java.util.HashMap;
import java.util.List;

/**
 * 表单插件
 */
public class TestStudyForm extends AbstractFormPlugin implements BeforeF7SelectListener,TabSelectListener {

    /**
     * 在此事件，可以侦听各个控件的插件事件。
     *
     * 说明：控件必须在registerListener方法中进行注册之后才会执行控件的事件。
     * 比如页面中有一个按钮控件，需要先在registerListener方法中添加该按钮控件，
     * 点击按钮时才会执行click、beforeClick等方法，否则不会执行，按钮控件相关事件请参考按钮控件 (kingdee.com)。其他控件同理。
     * @param e
     */
    @Override
    public void registerListener(EventObject e) {
        this.addClickListeners("test_button", "test_label");
        this.addItemClickListeners("tbmain");
        Tab tab = this.getView().getControl("ycsd_tabap");
        tab.addTabSelectListener(this);
        // 侦听基础资料字段的事件
        BasedataEdit fieldEdit = this.getView().getControl("language");
        fieldEdit.addBeforeF7SelectListener(this);
    }

    /**
     * 此事件触发时，新界面还没有显示出来，可以在此事件，取消界面的显示，或者修改显示参数。
     * @param e
     */
    @Override
    public void preOpenForm(PreOpenFormEventArgs e) {
        List<Plugin> plugins = e.getFormShowParameter().getFormConfig().getPlugins();
        Plugin plugin = new Plugin();
        plugin.setClassName("com.ycsd.invest.order.business.formplugin.TestFormPop");
        //添加插件
        plugins.add(plugin);
    }

    /**
     * 插件可以在此事件，自行创建界面数据包传回给系统，跳过系统内置的数据包创建过程。
     * 典型的应用场景：
     * 需要由外部传入完整地界面数据包，显示在界面上：就可以在此事件，先读取传入的数据包，然后传回表单，替代系统创建数据包的过程；
     * 动态添加字段时，系统内置创建的数据包，没有新字段的值，需要自行创建界面数据包.
     * @param e
     */
    @Override
    public void createNewData(BizDataEventArgs e) {
        //设置值会导致单据类型值为空
//        DynamicObject dynamicObject = new DynamicObject(this.getModel().getDataEntityType());
//        dynamicObject.set("amount", 123);
//        dynamicObject.set("form_title", "初始化标题");
//        dynamicObject.set("number", 7);
//        dynamicObject.set("number_two", 20);
//        e.setDataEntity(dynamicObject);
    }

    /**
     * 该事件为数据包创建之后的事件。插件在此对已创建好的模型数据包进一步加工，比如调整字段默认值，增加单据体默认行等。
     *
     * 由于部分字段的默认值难以通过设计器配置出来，如需要计算的值、根据系统参数选项决定的值，则需要写插件实现。
     * @param e
     */
    @Override
    public void afterCreateNewData(EventObject e) {
        this.getModel().setValue("amount", 1234);
        this.getModel().setValue("form_title", "初始化标题");
        this.getModel().setValue("number", 20);
        this.getModel().setValue("number_two", 123);
    }

    /**
     * 插件可以在此事件，根据各字段值数据，重新设置控件、字段的可用、可见性等。
     *
     * 不要在此事件，修改字段值。
     * @param e
     */
    @Override
    public void afterBindData(EventObject e) {
        if (this.getModel().getValue("number") != null && this.getModel().getValue("number_two") != null) {
            int number = Integer.parseInt(this.getModel().getValue("number").toString());
            int numberTwo = Integer.parseInt(this.getModel().getValue("number_two").toString());
            this.getModel().setValue("sum_val", numberTwo + number);
            this.getModel().setValue("multiplyVal", numberTwo * number);
        }
    }

    /**
     * 修改字段值之后触发。
     * 说明：
     * 界面数据初始时，不触发此事件，即在afterCreateNewData事件中，修改字段值，不会触发此事件；
     * 此事件在实体服务规则执行之后发生：用户手工录入字段值时，先执行与此字段相关的实体服务规则，然后再触发插件propertChanged事件。
     * @param e
     */
    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String fieldKey = e.getProperty().getName();

        if ("number".equals(fieldKey) || "number_two".equals(fieldKey)){
            int number = Integer.parseInt(this.getModel().getValue("number").toString());
            int number1 = Integer.parseInt(this.getModel().getValue("number_two").toString());
            this.getModel().setValue("multiplyVal", number1 * number);
        }
    }

    //普通单击事件
    @Override
    public void beforeClick(BeforeClickEvent evt) {
        Control source = (Control) evt.getSource();
        this.getView().showSuccessNotification("单击事件,标识: " + source.getKey());
    }

    //工具栏单击
    @Override
    public void beforeItemClick(BeforeItemClickEvent evt) {
        String itemKey = evt.getItemKey();
        // 当前表单数据包
        DynamicObject dataEntity = this.getModel().getDataEntity(false);
        switch (itemKey) {
            case "bar_submit" : {
                evt.setCancel(true);
//                this.getView().showTipNotification(
//                        String.format("提交失败，%s", dataEntity.getString("form_title")));
                DynamicObject type = (DynamicObject) this.getModel().getValue("form_type");
                HashMap<String, Object> map = DynamicObjectUtil.readPropValue(type);
                System.out.println(type);
                break;
            }
            case "bar_save" : {
                evt.setCancel(true);
                this.getView().showConfirm("确认保存？", MessageBoxOptions.YesNo, new ConfirmCallBackListener("save"));
                break;
            }
            case "bar_del" : {
                evt.setCancel(true);
                //查询
                DynamicObject dynamicObject = BusinessDataServiceHelper
                        .loadSingle(dataEntity.getString("id"), "ycsd_study_form");
                DynamicObjectCollection dynamicObjects = QueryServiceHelper.query("ycsd_study_form",
                        "id,billno,billstatus,languages",
                        new QFilter[]{new QFilter("id", QCP.equals, dataEntity.getString("id"))});
                this.getView().showConfirm("确认删除？", MessageBoxOptions.YesNo, new ConfirmCallBackListener("del"));
                break;
            }
            case "bar_close" : {
                Object number = this.getModel().getValue("number");
                if (number == null || (number instanceof Integer &&  Integer.parseInt(number.toString()) < 5)) {
                    evt.setCancel(true);
                    this.getView().showTipNotification("数字不能小于5");
                }
                break;
            }
            default: break;
        }
    }

    //确认回调
    @Override
    public void confirmCallBack(MessageBoxClosedEvent messageBoxClosedEvent) {

        String callBackId = messageBoxClosedEvent.getCallBackId();
        MessageBoxResult result = messageBoxClosedEvent.getResult();
        if ("save".equals(callBackId) && MessageBoxResult.Yes.equals(result)) {
            //开启子窗口
            FormShowParameter showParameter = new FormShowParameter();
            showParameter.setFormId("ycsd_test_alert");
            showParameter.getOpenStyle().setShowType(ShowType.Modal);
            CloseCallBack callBack = new CloseCallBack(this, "doAlert");
            showParameter.setCloseCallBack(callBack);
            this.getView().showForm(showParameter);
            //实体保存服务
            /*DynamicObject dataEntity = this.getModel().getDataEntity();
            //设置自定义编码后 获取编码
            CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(dataEntity.getDataEntityType().getName(),
                    dataEntity, String.valueOf(RequestContext.get().getOrgId()));
            String number = CodeRuleServiceHelper.getNumber(codeRule, dataEntity);
//            if (dataEntity.get("billno") != null) {
//                //存在时创建新实体 会导致基础资料为空
//                dataEntity = BusinessDataServiceHelper.newDynamicObject("ycsd_student_info");
//            }

            //获取基础资料
            DynamicObject formBasics = BusinessDataServiceHelper.loadSingle("ycsd_study_form_basic",
                    new QFilter[]{new QFilter("id", QCP.equals, "2236270899487599616")});
            DynamicObjectCollection basicDate = QueryServiceHelper.query("ycsd_study_form_basic",
                    "id", new QFilter[]{});
            DynamicObjectCollection languages = dataEntity.getDynamicObjectCollection("languages");
            //设置基础资料
            dataEntity.set("language", formBasics);
            //设置多选基础资料
            for (DynamicObject dynamicObject : basicDate) {
                languages.addNew().set("fbasedataid", dynamicObject.get("id"));
            }
            dataEntity.set("billno", number);
            SaveServiceHelper.saveOperate("save", dataEntity.getDataEntityType().getName(),
                    new DynamicObject[]{dataEntity}, OperateOption.create());
            this.getView().invokeOperation("refresh");*/
        } else if ("del".equals(callBackId) && MessageBoxResult.Yes.equals(result)) {
//            this.getView().invokeOperation("delete");
            DynamicObject dataEntity = this.getModel().getDataEntity();
            //逻辑删除 更新有效性
            dataEntity.set("valid", false);
            SaveServiceHelper.update(dataEntity, OperateOption.create());
            //删除
//            int i = DeleteServiceHelper.delete("ycsd_study_form",
//                    new QFilter[]{new QFilter("id", QCP.equals, this.getModel().getValue("id").toString())});
//            this.getView().showSuccessNotification("删除结果result: " + i);
            this.getView().invokeOperation("refresh");
        } else if ("close".equals(callBackId) && MessageBoxResult.Yes.equals(result)) {
            this.getView().invokeOperation("close");
        }
    }

    //页签切换
    @Override
    public void tabSelected(TabSelectEvent tabSelectEvent) {
        this.getView().showSuccessNotification("页签切换");

    }

    //基础资料选择前
    @Override
    public void beforeF7Select(BeforeF7SelectEvent beforeF7SelectEvent) {
        this.getView().showSuccessNotification("打开基础资料");
        String fieldKey = beforeF7SelectEvent.getProperty().getName();
        if (StringUtils.equals(fieldKey, "language")){
            // 添加过滤
            beforeF7SelectEvent.addCustomQFilter(QFilter.like("name", "文"));
        }
    }


    //页面关闭(包括子页面关闭)
    @Override
    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
        String actionId = closedCallBackEvent.getActionId();
        if ("doAlert".equals(actionId)) {
            this.getView().showSuccessNotification("回调成功,获取回调参数: " + closedCallBackEvent.getReturnData());
            this.getModel().setValue("form_title", closedCallBackEvent.getReturnData());
            //触发表单提交
            this.getView().invokeOperation("save");
        }
    }

    @Override
    public void beforeClosed(BeforeClosedEvent e) {
//        e.setCancel(true);
        this.getView().invokeOperation("refresh");
    }

}
